.TITLE PLSUB .IDENT /05.11/ ; ; Copyright (c) 1995-1999 by Mentec Inc., U.S.A. ; All rights reserved. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; PREVIOUSLY MODIFIED BY: ; ; J. R. KAUFFMAN ; B. S. MCCARTHY ; ; MODIFIED FOR RSX-11M-PLUS VERSION 3.0 BY: ; ; J. W. BERZLE ; ; MODIFIED FOR RSX-11M-PLUS VERSION 4.1 BY: ; ; B. S. MCCARTHY 1-APR-88 05.01 ; ; BM409 -- ADD $SRMAI TO LOOK FOR A MAIN PARTITION, CHANGE ; $SRNAM TO EXCLUDE MAIN PARTITIONS. ; ; Modified for RSX-11M-PLUS Version 4.5 by: ; ; D. Carroll 15-Feb-1993 05.10 ; ; DC111 - Correct subroutine $SETBP to correctly handle ; common regions on an mP system, w/ cache bypass ; ; Modified for RSX-11M-PLUS V4.6 by: ; ; D. Carroll 18-Oct-1995 05.11 ; DC404 - Include PSECT statement to allow ICB pool to be ; fully expanded during sysgen ; ; ; PROGRAM LOGICAL ADDRESS SPACE (PLAS) COMMON SUBROUTINES ; ; MACRO LIBRARY CALLS ; .IF DF P$$LAS .MCALL HDRDF$,HWDDF$,PCBDF$,TCBDF$ HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS .IFTF ;DC404 ;DC404 .IIF DF,K$$DAS&I$$CBP, .PSECT EXEC1 ;DC404 ;DC404 ;DC404 ;+ ; **-$SRNAM-SEARCH FOR NAMED PARTITION ; ; THIS ROUTINE SEARCHES FOR A NAMED PARTITION AND RETURNS A SUCCESS/ ; FAILURE INDICATION AND A POINTER TO THE PCB IF FOUND. ; ; INPUTS: ; ; R3=POINTER TO DOUBLE-WORD RAD50 NAME ; ; OUTPUTS: ; ; C=1 IF NO MATCH ON NAME ; ; C=0 IF NAMED PARTITION FOUND ; R2=PCB ADDRESS ;- .IFTF $SRNAM::MOV $CBDHD,R2 ;POINT TO FIRST ENTRY IN CBD BEQ 25$ ;IF EQ THERE IS NONE 10$: CMP P.NAM(R2),(R3) ;MATCH ON FIRST WORD OF NAME? BNE 20$ ;IF NE NO CMP P.NAM+2(R2),2(R3) ;MATCH ON SECOND WORD OF NAME? BEQ 30$ ;IF EQ YES 20$: MOV P.CBDL(R2),R2 ;POINT TO NEXT MAIN PCB BNE 10$ ;IF NE THERE IS ONE 25$: SEC ;C-SET ON NO MATCH 30$: RETURN ; ;+ ; **-$SRMAI-SEARCH FOR NAMED MAIN PARTITION ; ; THIS ROUTINE SEARCHES FOR A NAMED MAIN PARTITION AND RETURNS A ; FAILURE SUCCESS/INDICATION AND A POINTER TO THE PCB IF FOUND. ; ; INPUTS: ; ; R3=POINTER TO DOUBLE-WORD RAD50 NAME ; ; OUTPUTS: ; ; C=1 IF NO MATCH ON NAME ; ; C=0 IF NAMED PARTITION FOUND ; R2=PCB ADDRESS ;- .IFTF $SRMAI::MOV $PARHD,R2 ;POINT TO FIRST MAIN PCB 10$: CMP P.NAM(R2),(R3) ;MATCH ON FIRST WORD OF NAME? BNE 20$ ;IF NE NO CMP P.NAM+2(R2),2(R3) ;MATCH ON SECOND WORD OF NAME? BEQ 30$ ;IF EQ YES 20$: MOV (R2),R2 ;POINT TO NEXT MAIN PCB BNE 10$ ;IF NE THERE IS ONE SEC ;C-SET ON NO MATCH 30$: RETURN ; .IFT ;+ ; **-$CKACC-CHECK DESIRED ACCESS ; ; THIS ROUTINE CHECKS IF THE DESIRED ACCESS OF A TASK TO A REGION ; IS ALLOWED. THE BITS IN THE PROTECTION WORD ARE ARRANGED IN THE ; FOLLOWING ORDER: ; ; [WORLD,GROUP,OWNER,SYSTEM] ; 15 0 ; ; THE BITS WITHIN EACH CATEGORY IN THE PROTECTION WORD ARE ARRANGED ; IN THE FOLLOWING ORDER: ; ; DELETE EXTEND WRITE READ ; 3 2 1 0 ; ; A BIT SET MEANS THE CORRESPONDING ACCESS IS NOT ALLOWED. ; ; INPUTS: ; ; R0=DESIRED ACCESS MASK IN LOW FOUR BITS ; R1=CURRENT UIC OF TASK ; R2=PCB ADDRESS OF REGION ; ; OUTPUTS: ; ; R0,R1 ARE MODIFIED ; ; DIRECTIVE STATUS OF D.RS16 RETURNED IF ACCESS DENIED. ;- $CKACC::MOV #30$,-(SP) ;PUSH COROUTINE ADDRESS BIC #^C17,R0 ;CLEAR ALL BUT DESIRED ACCESS MASK 10$: SWAB R1 ;REVERSE GROUP AND OWNER IN UIC WORD CALL @(SP)+ ;CHECK IF QUALIFIED IN NEXT CATEGORY BNE 20$ ;IF NE NO BIT R0,P.PRO(R2) ;ALLOWED ACCESS IN THIS CATEGORY? BNE 20$ ;IF NE NO TST (SP)+ ;POP COROUTINE ADDRESS RETURN ;RETURN TO CALLER 20$: ASL R0 ;SHIFT MASK TO NEXT CATEGORY ASL R0 ; ASL R0 ; ASL R0 ; BR 10$ ;CHECK ACCESS IN THIS CATEGORY 30$: CMPB R1,#10 ;SYSTEM UIC? BHI 40$ ;IF HI NO SEZ ;SET FLAG FOR ACCESS CHECK 40$: CALL @(SP)+ ;CHECK ACCESS AND SHIFT MASK CMP R1,P.OWN(R2) ;OWNER UIC? CALL @(SP)+ ;CHECK ACCESS AND SHIFT MASK CMPB R1,P.OWN+1(R2) ;SAME GROUP? CALL @(SP)+ ;CHECK ACCESS AND SHIFT MASK SEZ ;INSURE CHECK FOR WORLD ACCESS CALL @(SP)+ ;CHECK ACCESS DRSTS D.RS16 ;ACCESS DENIED IF WE GET HERE ;+ ; **-$CRATT-CREATE ATTACHMENT DESCRIPTOR ; ; THIS ROUTINE CREATES AN ATTACHMENT DESCRIPTOR AND INSERTS IT IN THE ; NECESSARY QUEUES. ; ; INPUTS: ; ; R2=PCB ADDRESS OF REGION BEING ATTACHED TO ; R4=ACCESS CODE ; R5=TCB ADDRESS OF ATTACHING TASK ; ; OUTPUTS: ; ; C=0 IF SUCCESSFUL ; R1=ADDRESS OF ATTACHMENT DESCRIPTOR ; R0 IS MODIFIED ; C=1 IF AN ATTACHMENT DESCRIPTOR COULD NOT BE ALLOCATED ; R0,R1 ARE MODIFIED ;- .IFTF $CRATT::MOV R3,-(SP) ;SAVE R3 MOV R2,-(SP) ;SAVE PCB ADDRESS MOV #A.LGTH,R1 ;PICK UP ATTACHMENT DESCRIPTOR SIZE CALL $ALOCB ;ALLOCATE THE ATTACHMENT DESCRIPTOR BCS 10$ ;IF CS ALLOCATION FAILURE ADD R0,R1 ;POINT PAST END OF ATTACHMENT DESCRIPTOR MOV (SP),-(R1) ;SET PCB ADDRESS (A.PCB) MOV R4,-(R1) ;INIT STATUS AND MAP COUNT (A.STS) BIC #^C17,(R1) ;CLEAR ALL BUT ACCESS BITS (A.STS) TST -(R1) ;POINT TO TCBL THREAD WORD (A.TCBL) MOV R5,R0 ;POINT TO TCB ATTACHMENT LISTHEAD ADD #T.ATT,R0 ; CALL $QINSF ;INSERT DESCRIPTOR AT END OF QUEUE MOV R5,-(R1) ;SET TCB ADDRESS (A.TCB) CLRB -(R1) ;ZERO I/O COUNT (A.IOC) MOVB T.PRI(R5),-(R1) ;INIT PRIORITY TO TASK PRIORITY (A.PRI) TST -(R1) ;POINT TO PCBL THREAD (A.PCBL) MOV (SP),R0 ;POINT TO PCB ATTACHMENT LISTHEAD ADD #P.ATT,R0 ; CALL $QINSP ;INSERT IN QUEUE BY PRIORITY CLC ;INDICATE SUCCESS 10$: MOV (SP)+,R2 ;RESTORE PCB ADDRESS MOV (SP)+,R3 ;RESTORE R3 RETURN ; .IFT ;+ ; **-$SRATT-SEARCH FOR ATTACHMENT DESCRIPTOR ; ; THIS ROUTINE VERFIES IF A VALID REGION ID WAS PASSED IN A PLAS DIRECTIVE ; BY SEARCHING FOR THE CORRESPONDING ATTACHMENT DESCRIPTOR IN THE TCB'S ; ATTACHMENT QUEUE. ; ; INPUTS: ; ; (R3)=REGION ID TO VERIFY ; 0 FOR TASK REGION ; 1-17 FOR OTHER STATICALLY LINKED REGIONS ; R5=TCB ADDRESS OF CURRENT TASK ; ; OUTPUTS: ; ; R5=ADDRESS OF ATTACHMENT DESCRIPTOR ; ; D.RS86 IS RETURNED IF THE ATTACHMENT DESCRIPTOR CANNOT BE FOUND. ;- $SRATT::MOV T.ATT(R5),R5 ;POINT TO FIRST ATTACHMENT DESCRIPTOR MOV (R3),-(SP) ;SAVE REGION ID CMP (SP),#17 ;STATICALLY LINKED REGION? BHI 9$ ;NO IF HI 5$: DEC (SP) ;SEARCH FOR PROPER ATTACHMENT DESCR BLT 20$ ;IF LT, FOUND IT MOV (R5),R5 ;POINT TO NEXT ATT DESCR BEQ 15$ ;IF EQ, END OF LIST BR 5$ ;GO AGAIN 9$: ADD #A.TCBL,(SP) ;ADD BIAS TO LINK WORD 10$: CMP R5,(SP) ;MATCH ON THIS DESCRIPTOR? BEQ 20$ ;IF EQ YES MOV (R5),R5 ;ELSE POINT TO NEXT DESCRIPTOR (A.TCBL) BNE 10$ ;IF NE THERE IS ONE 15$: DRSTS D.RS86 ;INVALID REGION ID 20$: SUB #A.TCBL,R5 ;POINT TO START OF ATTACHMENT DESCRIPTOR TST (SP)+ ;CLEAN STACK RETURN ; ;+ ; **-$SRWND-SEARCH FOR SPECIFIED ADDRESS WINDOW ; ; THIS ROUTINE VERIFIES THAT THE SPECIFIED ADDRESS WINDOW ID CORRESPONDS ; TO A VALID ESTABLISHED ADDRESS WINDOW. ; ; INPUTS: ; ; (R3)=ADDRESS WINDOW ID ; R4=ADDRESS OF CURRENT TASK HEADER ; R5=TCB ADDRESS OF CURRENT TASK ; ; OUTPUTS: ; ; R4=POINTER TO SPECIFIED WINDOW BLOCK ; R0 IS MODIFIED. ; ; D.RS87 IS RETURNED IF THE SPECIFIED ADDRESS WINDOW IS INVALID ;- $SRWND::MOV H.WND(R4),R4 ;POINT TO NUMBER OF WINDOWS MOVB (R3),R0 ;PICK UP ADDRESS WINDOW ID (W.NID) BEQ 10$ ;IF EQ ILLEGAL .IF DF U$$DAS CMP #1,R0 ;ADDRESS WINDOW 1 ? BNE 5$ ;IF NE NO BIT #T4.DSP,T.ST4(R5) ;TASK USE USER D SPACE ? BNE 10$ ;IF NE YES, CAN'T CHANGE WINDOW ONE 5$: ;REFERENCE LABEL .ENDC ; DF U$$DAS CMP R0,(R4)+ ;WINDOW ID TOO LARGE? BHIS 10$ ;IF HIS YES ASL R0 ;CONVERT WINDOW ID TO 8 WORD OFFSET ASL R0 ; ASL R0 ; ASL R0 ; ADD R0,R4 ;POINT TO ADDRESS WINDOW TST W.BSIZ(R4) ;IS IT AN ESTABLISHED ADDRESS WINDOW? BEQ 10$ ;IF EQ NO RETURN ; 10$: DRSTS D.RS87 ;INVALID ADDRESS WINDOW ;+ ; **-$UNMAP-UNMAP ADDRESS WINDOW ; ; THIS ROUTINE SEARCHES FOR AND CONDITIONALLY UNMAPS THE SPECIFIED ; ADDRESS WINDOW. ; ; INPUTS: ; ; R4=ADDRESS OF WINDOW TO BE UNMAPPED ; ; OUTPUTS: ; ; R0 IS MODIFIED ; ; C=1 IF UNMAPPING WAS PERFORMED ;- .ENABL LSB 1$: RETURN ;RETURN TO KEEP BRANCH FROM BREAKING $UNMAP::TST (R4) ;IS WINDOW MAPPED? (W.BPCB) BEQ 1$ ;IF EQ, WINDOW NOT MAPPED MOV R3,-(SP) ;SAVE REGISTERS MOV R2,-(SP) ; MOV R1,-(SP) ; .IF DF F$$MAP&X$$HDR&P$$LAS TST $FMAPP ;TASK USE FAST MAP? BEQ 5$ ;IF EQ NO MOVB W.BFPD(R4),R0 ;GET FIRST PDR ADDRESS BPL 5$ ;IF PL NOT USER WINDOW, ;CAN'T BE SET FAST MAP ASL R0 ;ADJUST TO ASL R0 ;QUADWORD OFFSET BIC #177407,R0 ;REMOVE UNNEEDED BITS ADD $FMAPP,R0 ;POINT TO BLOCK CLR (R0) ;INDICATE UNUSED 5$: .ENDC ; DF F$$MAP&X$$HDR&P$$LAS MOV W.BATT(R4),R0 ;PICK UP ADDRESS OF ATTACHMENT DESCRIPTOR CLR W.BATT(R4) ;CLEAR ATTACHMENT DESCRIPTOR POINTER DECB A.MPCT(R0) ;DECREMENT MAPPING COUNT MOVB A.MPCT(R0),-(SP) ;SAVE MAPPING COUNT FOR TEST LATER MOV A.TCB(R0),R1 ;POINT TO TASK TCB ADDRESS .IF DF X$$HDR MOV $SAHPT,R0 ;GET ADDRESS OF CURRENT TASK HEADER .IFF MOV $HEADR,R0 ;GET ADDRESS OF CURRENT TASK HEADER .ENDC .IF DF S$$LIB!U$$DAS MOV H.SMAP(R0),-(SP) ;GET SUPER MAPPING MASK FOR LATER .ENDC ; DF S$$LIB!U$$DAS MOV H.WND(R0),R2 ;GET ADDRESS OF FIRST WINDOW BLOCK MOVB W.BFPD(R4),R0 ;POINT TO FIRST USER PDR .IF DF S$$LIB BPL 17$ ;IF PL SUPER WINDOW .IFTF ; DF S$$LIB 10$: ;REFERENCE LABEL .IF DF U$$DAS CMP #UDSDR0,R0 ;USER D SPACE WINDOW ? BLOS 140$ ;IF LOS YES, HANDLE USER D SPACE .ENDC ; DF U$$DAS TST W.BLVR+2(R2) ;IS THE TASK PRIVILEGED? BEQ 14$ ;IF EQ NO MOV KISAR0-UINDR0(R0),UINAR0-UINDR0(R0) ;RESTORE PRV ;MAPPING .IF DF M$$PRO MOV #177406,(R0)+ ;RESTORE R/W 4K BYPASS ACCESS .IFF ; DF M$$PRO MOV #77406,(R0)+ ;RESTORE R/W 4K ACCESS .ENDC ; DF M$$PRO .IF DF U$$DAS BITB $BTMSK-UINDR0-2(R0),1(SP) ;THIS APR MAPPED THROUGH ;DISCRETE USER D WINDOW BNE 15$ ;IF NE YES, LEAVE USER/SUPER D ALONE MOV KISAR0-UINDR0-2(R0),UDSAR0-UINDR0-2(R0) ;MAP USER D ;TO EXEC .IF DF M$$PRO MOV #177406,UDSDR0-UINDR0-2(R0) ;RESTORE R/W 4K BYPASS ACCESS .IFF ; DF M$$PRO MOV #77406,UDSDR0-UINDR0-2(R0) ;RESTORE R/W 4K ACCESS .ENDC ; DF M$$PRO .ENDC ; DF U$$DAS .IFT ; DF S$$LIB BITB $BTMSK-2-UINDR0-2(R0),(SP) ;SUPER I MAPPED TO USER D ? BNE 15$ ;IF NE NO MOV KISAR0-UINDR0-2(R0),SDSAR0-UINDR0-2(R0) ;MAP SUPER D TO ;EXEC .IF DF M$$PRO MOV #177406,SDSDR0-UINDR0-2(R0) ;RESTORE R/W 4K BYPASS ACCESS .IFF ; DF M$$PRO MOV #77406,SDSDR0-UINDR0-2(R0) ;RESTORE R/W 4K ACCESS .ENDC ; DF M$$PRO .IFTF BR 15$ ; 14$: CLR (R0)+ ;CLEAR NEXT USER PDR .IF DF U$$DAS BITB $BTMSK-UINDR0-2(R0),1(SP) ;THIS USER D APR MAPPED BY ;EXPLICIT D SPACE WINDOW BNE 15$ ;IF NE YES, DON'T CHANGE CLR UDSDR0-UINDR0-2(R0) ;UNMAP USER D SPACE .ENDC ; DF U$$DAS .IFT ; DF S$$LIB BITB $BTMSK-2-UINDR0-2(R0),(SP) ;SUPER D MAPPED TO USER D ;FOR THIS APR ? BNE 15$ ;IF NE NO CLR SDSDR0-UINDR0-2(R0) ;UNMAP SUPER D SPACE .IFTF ; DF S$$LIB .IF DF U$$DAS BR 15$ ;SKIP USER D CODE 140$: BICB $BTMSK-UDSDR0(R0),1(SP) ;INDICATE REMAPPING TO I SPACE MOV UINAR0-UDSDR0(R0),UDSAR0-UDSDR0(R0) ;MAP USER D TO USER I MOV UINDR0-UDSDR0(R0),(R0)+ ;AND SET SAME ACCESS .IF DF S$$LIB BITB $BTMSK-2-UDSDR0-2(R0),(SP) ;THIS SUPER D APR MAPPED TO ;USER D SPACE BNE 15$ ;IF NE NO MOV UINAR0-UDSDR0-2(R0),SDSAR0-UDSDR0-2(R0) ;MAP SUPER D TO ;USER D MOV UINDR0-UDSDR0-2(R0),SDSDR0-UDSDR0-2(R0) ;AND SET ACCESS .ENDC ; DF S$$LIB .ENDC ; DF U$$DAS 15$: DECB W.BNPD(R4) ;DONE YET? BGT 10$ ;IF GT NO .IFT ; DF S$$LIB BR 18$ ;SKIP SUPER I SPACE WINDOW CODE 17$: ADD #SDSDR0,R0 ;ADJUST TO SUPER D SPACE PDRS DECB $SUPFL ;COUNT ONE LESS SUPERVISOR MODE WINDOW BNE 170$ ;IF NE THERE STILL ARE SOME BIC #10,SR3 ;DISABLE CSM INSTRUCTION BIS #PMODE!CMODE,$STACK-2 ;FORCE EXECUTION TO USER MODE 170$: BITB $BTMSK-2-SDSDR0(R0),(SP) ;THIS APR OVERMAPPED BEQ 171$ ;IF EQ NO, DON'T TOUCH CLR (R0)+ ;CLEAR NEXT SUPER D PDR BR 172$ ;GO DO NEXT ONE 171$: TST (R0)+ ;SKIP THIS APR 172$: DECB W.BNPD(R4) ;DONE YET ? BGT 170$ ;IF GT NO .ENDC ; DF S$$LIB 18$: ;REFERENCE LABEL .IF DF U$$DAS!S$$LIB MOV $SAHPT,R0 ;GET ADDRESS OF TASK HEADER MOVB 1(SP),H.DMAP(R0) ;RESTORE D SPACE MAPPING MASK TO HEADER TST (SP)+ ;CLEAN OFF MAPPING MASKS .ENDC ; DF U$$DAS!S$$LIB MOV R1,R0 ;COPY TCB ADDRESS FOR DEACCESS MOV (R4),R1 ;POINT TO PCB TO DEACCESS .IF DF M$$PRO CALL $RESBP ;RESET CACHE BYPASS AS APPROPRIATE .IFTF TSTB (SP)+ ;WAS THIS LAST MAP THROUGH ATTACHMENT ? BNE 20$ ;IF NE NO, DON'T DEACCESS REGION YET MOV R0,-(SP) ;SAVE REGISTERS MOV R1,-(SP) ; CALL $DEARG ;DEACCESS REGION MOV (SP)+,R1 ;RESTORE REGISTERS MOV (SP)+,R0 ; 20$: CLR (R4) ;UNMAP WINDOW (W.BPCB) .IFT .IF DF M$$EXT CMP P.REL(R1),#177600 ;IS REGION IN THE IO PAGE? .IFF CMP P.REL(R1),#7600 ;IS REGION IN THE IO PAGE? .ENDC BLO 95$ ;NO IF LO CALL $SETAT ;RECALULATE TASK AFFINITY .IFTF 95$: MOV (SP)+,R1 ;RESTORE REGISTERS MOV (SP)+,R2 ; MOV (SP)+,R3 ; SEC ;RETURN CS FOR WINDOW UNMAPPED 100$: RETURN ; .ENDC .ENDC ; DF P$$LAS .DSABL LSB ;+ ; **-$GTMCT-DETERMINE NUMBER OF MAPPED TASKS ; ; THIS ROUTINE CALCULATES THE NUMBER OF WINDOWS MAPPED TO A GIVEN REGION. ; THE VALUE RETURNED IS FOR DETERMINING IF CACHE BYPASS ; IS NECESSARY FOR THIS REGION. ; ; INPUTS: ; ; R1=PCB ADDRESS ; ; OUTPUTS: ; ; R2=NUMBER OF WINDOWS MAPPED TO THE REGION ; R2=0 FOR READ ONLY COMMONS ; R2=1 IF ONE WINDOW IS MAPPED ; R0=ADDRESS OF TASK'S ATTACHMENT DESCRIPTOR ; R2=2 IF 2 OR MORE WINDOWS ARE MAPPED TO THIS REGION ; ; R0 MODIFIED ;- .IF DF M$$PRO $GTMCT::CLR R2 ;ASSUME NO MAPPED TASKS BIT #P2.RON,P.ST2(R1) ;READ ONLY REGION? BNE 30$ ;YES IF NE MOV R1,-(SP) ; CLR -(SP) ;RESERVE A WORD ON THE STACK ADD #P.ATT,R1 ;POINT TO ATT DESCR LIST 10$: MOV (R1),R1 ;POINT TO NEXT ATT DESCR BEQ 20$ ;IF EQ END OF LIST MOVB A.MPCT-A.PCBL(R1),R0 ;TASK MAPPED? BEQ 10$ ;IF EQ NO MOV R1,(SP) ;SAVE ATTACHMENT DESCR ADDRESS ADD R0,R2 ;CALCULATE TOTAL NUMBER OF TASKS MAPPED CMP R2,#2 ;AT LEAST TWO TASKS MAPPED? BLT 10$ ;IF LT NO 20$: SUB #A.PCBL,(SP) ;POINT TO START OF ATT DESCR MOV (SP)+,R0 ;GET ATT DESCR ADDRESS MOV (SP)+,R1 ;RESTORE R1 30$: RETURN ; ;+ ; **-$STCXT-SET MAPPING CONTEXT ; ; THIS ROUTINE RELOADS THE PDRS FOR A SPECIFIED REGION. ; ; INPUTS: ; ; IF CALLED TO FORCE SECOND MAPPED TASK TO BYPASS THE CACHE: ; ; R4=ATTACHMENT DESCRIPTOR FOR FIRST TASK TO MAP TO REGION ; R5=ATTACHMENT DESCRIPTOR FOR SECOND TASK TO MAP TO REGION ; ; IF CALLED TO RELOAD THE PDRS FOR THE ONLY TASK MAPPED TO THIS REGION: ; ; R4=ATTACHMENT DESCRIPTOR FOR ONLY TASK MAPPED TO REGION ; R5=0 ; ; OUTPUTS: ; ; THE PDRS ARE SET UP SO THAT ACCESSES TO THIS REGION BYPASS CACHE ; AS APPROPRIATE. ; ;- $STCXT:: ;REFERENCE LABEL .IF DF X$$HDR MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING .ENDC MOV $TKTCB,R0 ;GET TCB ADDRESS OF CURRENT TASK BEQ 100$ ;IF EQ NO CURRENT TASK BIT #TS.RUN,T.STAT(R0) ;IS TASK RUNNING? BEQ 100$ ;NO IF EQ MOV T.PCB(R0),R0 ;GET PCB ADDRESS .IF DF X$$HDR .IFTF MOV P.HDR(R0),R1 ;GET HEADER ADDRESS .IFT BNE 10$ ;IF NE, RESIDENT HEADER MOV P.REL(R0),KISAR6 ;MAP TO NON RESIDENT HEADER MOV #140000,R1 ;POINT TO NON RESIDENT HEADER 10$: .ENDC MOV R4,R2 ;COPY ATT DESCR ADDRESS OF CALLER CALL $SRWAT ;SEARCH FOR WINDOW BCS 100$ ;IF CS NOT FOUND TST W.BPCB(R0) ;IS WINDOW STILL MAPPED? BEQ 100$ ;NO IF EQ BIT #WB.NBP,W.BLPD(R0) ;CACHE BYPASS NOT DESIRED? BNE 100$ ;YES IF NE DO NOT BYPASS CLR -(SP) ;RESERVE A WORD ON THE STACK MOVB W.BNPD(R0),(SP) ;GET NUMBER OF PDRS TO LOAD MOV W.BLPD(R0),R2 ;GET CONTENTS OF LAST PDR BIC #77777,R2 ;KEEP ONLY THE BYPASS BIT MOVB W.BFPD(R0),R1 ;GET ADDRESS OF FIRST PDR .IF DF S$$LIB BMI 30$ ;IF MI USER WINDOW ADD #SISDR0,R1 ;POINT TO SUPERVISOR PDR .IFTF 30$: BIC #100000,(R1) ;CLEAR BYPASS INDICATOR BIS R2,(R1)+ ;SET BYPASS BIT AS APPROPRIATE .IFT CMP R1,#UISDR0 ;USER WINDOW? BLO 40$ ;NO IF LO MOV -2(R1),SDSDR0-UISDR0-2(R1) ;RELOAD PDR .ENDC 40$: DEC (SP) ;FINISHED LOADING PDRS? BGT 30$ ;IF GT NO TST (SP)+ ;CLEAN THE STACK 100$: ;REFERENCE LABEL .IF DF X$$HDR MOV (SP)+,KISAR6 ;RESTORE KERNEL MAPPING .ENDC TST R5 ;RESET BYPASS BEQ 110$ ;IF EQ YES, NO TASK TO UNBLOCK MOV A.TCB(R5),R0 ;GET TCB ADDRESS DEC T.STAT(R0) ;UNBLOCK THE TASK CALLR $SETCR ;SET A CONDITIONAL SCHEDULE REQUEST 110$: RETURN ; ;+ ; **-$SRWAT-SEARCH FOR WINDOW ; ; THIS ROUTINE SEARCHES FOR A MAPPED WINDOW WITH A GIVEN ; ATTACHMENT DESCRIPTOR. ; ; INPUTS: ; ; R1=HEADER ADDRESS ; R2=ATTACHMENT DESCRIPTOR ADDRESS ; ; OUTPUTS: ; ; C=1 IF NO MATCH ON ATTACHMENT DESCRIPTOR ; ; C=0 IF WINDOW FOUND ; R0=WINDOW ADDRESS ; ; ; R0 MODIFIED ;- $SRWAT::MOV H.WND(R1),R0 ;POINT TO NUMBER OF WINDOWS MOV (R0)+,-(SP) ;GET NUMBER OF WINDOWS 10$: CMP W.BATT(R0),R2 ;ATTACHMENT DESCRIPTORS MATCH? BNE 15$ ;IF NE NO TSTB A.MPCT(R2) ;IS WINDOW MAPPED? BNE 20$ ;IF NE YES 15$: ADD #W.BLGH,R0 ;POINT TO NEXT WINDOW DEC (SP) ;ANY WINDOWS LEFT? BGT 10$ ;IF GT YES SEC ;WINDOW NOT FOUND 20$: MOV PC,(SP)+ ;CLEAN THE STACK WITHOUT MODIFYING CARRY RETURN ; ;+ ; **-$RESBP-RESET CACHE BYPASS ; ; THIS ROUTINE WILL RESET CACHE BYPASS FOR A REGION ; IF ONLY ONE WINDOW IS MAPPED TO THE REGION. ; ; INPUTS: ; ; R1=PCB ADDRESS ; ; OUTPUTS: ; ; CACHE BYPASS IS DISABLED IF ONLY ONE WINDOW IS MAPPED ; TO THE REGION. ; ;- $RESBP::SAVNR ;SAVE REGISTERS MOV R3,-(SP) ; MOV R2,-(SP) ; MOV R1,-(SP) ; MOV R0,-(SP) ; .IF DF X$$HDR MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING .ENDC CALL $GTMCT ;GET NUMBER OF TIMES REGION IS MAPPED TO DEC R2 ;ONLY MAPPED ONCE? BNE 100$ ;IF NE NO MOV A.TCB(R0),R2 ;GET TCB ADDRESS MOV T.PCB(R2),R2 ;GET PCB ADDRESS BIT #PS.OUT!PS.CKP!PS.CKR,P.STAT(R2) ;IS TASK CHECKPOINTED? BEQ 10$ ;IF EQ NO BICB #AS.SBP,A.STAT(R0) ;CLEAR BYPASS BIT BISB #AS.RBP,A.STAT(R0) ;INDICATE BYPASS IS NOT NECESSARY BR 100$ ; .IF DF X$$HDR .IFTF 10$: MOV P.HDR(R2),R1 ;GET HEADER ADDRESS .IFT BNE 20$ ;IF NE, RESIDENT HEADER MOV P.REL(R2),KISAR6 ;MAP TO NON RESIDENT HEADER MOV #140000,R1 ;POINT TO NON RESIDENT HEADER 20$: .ENDC MOV R0,R2 ;COPY ATTACHMENT DESCRIPTOR ADDRESS CALL $SRWAT ;SEARCH FOR WINDOW BCS 100$ ;IF CS NOT FOUND BIC #100000,W.BLPD(R0) ;RESET CACHE BYPASS IN LAST PDR BIT #WB.NBP!WB.BPS,W.BLPD(R0) ;SHOULD TASK RELOAD PDRS? BNE 100$ ;IF NE NO MOV R2,R4 ;COPY ATT DESCR FOR ONLY TASK MAPPED CLR R5 ; MOV A.TCB(R2),R2 ;GET TCB ADDRESS OF MAPPED TASK BIT #TS.RUN,T.STAT(R2) ;IS TASK RUNNING? BEQ 100$ ;IF EQ NO MOVB T.CPU(R2),R2 ;FIND CPU TASK IS RUNNING ON ASL R2 ;CONVERT TO WORD INDEX MOV $BTMSK(R2),R2 ;GET CPU BIT MOV #$STCXT,R3 ;GET ADDRESS OF ROUTINE TO RELOAD PDRS CALL $EXROP ;EXECUTE $STCXT ON CORRECT PROCESSOR 100$: ;REFERENCE LABEL .IF DF X$$HDR MOV (SP)+,KISAR6 ;RESTORE APR 6 MAPPING .ENDC MOV (SP)+,R0 ;RESTORE REGISTERS MOV (SP)+,R1 ; MOV (SP)+,R2 ; MOV (SP)+,R3 ; RETURN ;+ ; **-$SETBP- Setup for cache bypass ; ; This routine will determine if only one window is mapped to this ; region. If so, the task mapped to this region is notified to bypass ; cache as necessary. ; ; Inputs: ; ; R0 = TCB address ; R1 = PCB address ; R3 = Window address of task about to map to this region ; ; Outputs: ; ; Task mapped to this region is notified as necessary. ; Task about to map is blocked (if necessary) until task ; already mapped reloads its context. ; ;- $SETBP::SAVNR ; Save registers .IF DF X$$HDR MOV KISAR6,-(SP) ; Save current mapping .ENDC ;+ ; Determine if any cache bypass is needed ... ;- BIT #P2.RON,P.ST2(R1) ; is the region R/O BNE 5$ ; if EQ, yes, skip all of this ... JMP 120$ ; finish up, don't need to do anything 5$: MOV W.BATT(R3),R5 ; extract this requests window ADB BICB #AS.SBP!AS.RBP,A.STAT(R5) ; indicate no cache bypass needed MOV R1,R4 ; Copy the PCB address ADD #P.ATT,R4 ; and initialize our loop 10$: MOV R3,-(SP) ; MOV R2,-(SP) ; MOV R1,-(SP) ; MOV R0,-(SP) ; MOV R4,R3 ; copy the listhead to R3 20$: MOV (R3),R3 ; get next accessor BEQ 100$ ; no writers are mapped TSTB A.MPCT(R3) ; is the region mapped BEQ 20$ ; if EQ, nope, try next BITB #AS.WRT,A.STAT(R3) ; mapped w/ write access? BEQ 20$ ; if EQ, nope, check next accessor 30$: MOV (R4),R4 ; Get the next link word ... BEQ 100$ ; if EQ, end of list, finish up TSTB A.MPCT(R4) ; is the region mapped via this ADB BEQ 30$ ; if EQ, no try next region CMP A.TCB(R4),A.TCB(R5); is this the same task mapping? BEQ 30$ ; if EQ, yes, no need to worry yet ... ;+ ; We will require cache bypass to be implemented, ; based on the following criteria -- ; ; - The requesting task is not the only accessor. ; - At least one window is mapped with write access. ;- BITB #AS.SBP,A.STAT(R5) ; first pass through this way? BNE 60$ ; if NE, nope, our task mapping is updated ;+ ; Scan through the TCB attachment list, and update all windows ; to be set as cache bypass ... ;- MOV R4,-(SP) ; save R4 for a bit ... MOV A.TCB(R5),R4 ; get the requestors TCB address ADD #T.ATT-A.TCBL,R4 ; and point to this tasks attachments list 40$: MOV A.TCBL(R4),R4 ; get the next attachment descriptor BEQ 50$ ; if EQ, end of attachement list ... SUB #A.TCBL,R4 ; and point to the beginning of the ADB CMP A.PCB(R4),A.PCB(R5) ; same PCB address? BNE 40$ ; nope, continue on ... MOV R4,-(SP) ; save this ADB address MOV A.TCB(R4),R1 ; extract the TCB address INC T.STAT(R1) ; increment the blocking count CALL $STCXT ; update the window context MOV (SP)+,R4 ; restore the ADB address BR 40$ ; and get the next attachment 50$: MOV (SP)+,R4 ; Restore our saved ADB pointer 60$: BISB #AS.SBP,A.STAT(R5) ; indicate cache bypass needed MOV A.TCB(R4),R2 ; Get the TCB address of the mapped task MOV T.PCB(R2),R1 ; and the PCB address BIT #PS.OUT!PS.CKP!PS.CKR,P.STAT(R1) ; is the task out? BEQ 70$ ; nope, the task is in memory BISB #AS.SBP,A.STAT(R4) ; indicate that bypass is requested BICB #AS.RBP,A.STAT(R4) ; and remove the no bypass option BR 30$ ;+ ; The task is in memory ... ; - The window descriptor in the task header must ; be updated to indicate that cache bypass is in effect ; - If the task is active on another processor, we will need to ; block the requesting task until we have updated the cache ; bypass status of all other mapped tasks. ;- 70$: MOV R4,R2 ; Copy attachment descriptor address MOV A.TCB(R4),R1 ; Get the TCB address MOV T.PCB(R1),R1 ; and the mapped tasks PCB address .IF DF X$$HDR MOV R1,R0 ; Copy PCB pointer MOV P.HDR(R1),R1 ; Get header address BNE 80$ ; If NE, resident header MOV P.REL(R0),KISAR6 ; Map to non resident header MOV #140000,R1 ; Point to non resident header 80$: .IFF ;DF,X$$HDR MOV P.HDR(R1),R1 ; Get header address .ENDC ;DF,X$$HDR CALL $SRWAT ; Search for window BCS 30$ ; If CS, not found, but I have the ADB! BIS #100000,W.BLPD(R0) ; Set up last PDR to bypass MOV A.TCB(R4),R1 ; Extract the target mapped TCB BIT #TS.RUN,T.STAT(R1) ; Is task running on some processor? BEQ 30$ ; If EQ, no MOV R1,-(SP) ; Save our current TCB address MOV A.TCB(R5),R0 ; and extract the requesting tasks TCB INC T.STAT(R0) ; Block calling task CALL $SETCR ; Set a schedule request MOV (SP)+,R1 ; Restore the currently mapped tasks TCB MOVB T.CPU(R1),R2 ; Get CPU ID on which task is running ASL R2 ; Convert to word index MOV $BTMSK(R2),R2 ; Get run mask MOV #$STCXT,R3 ; Set address of routine to call CALL $EXROP ; Load the context for this task, in context BR 30$ ; and continue the scan of the remaining ADBs 100$: BICB #AS.SBP,A.STAT(R5) ; release the set bypass status 110$: MOV (SP)+,R0 ; Restore registers MOV (SP)+,R1 ; MOV (SP)+,R2 ; MOV (SP)+,R3 ; 120$: ; Reference label .IF DF X$$HDR MOV (SP)+,KISAR6 ; Restore kernel mapping .ENDC RETURN ; .ENDC ; DF M$$PRO ;+ ; **-$DELRG-DELETE REGION ; ; THIS ROUTINE ASSUMES ALL CHECKS HAVE BEEN MADE ON WHETHER A REGION MAY ; BE DELETED OR NOT. IT UNCONDITIONALLY DELETES THE REGION REGARDLESS ; OF WHAT STATE THE REGION IS CURRENTLY IN. ; ; WHEN THE REGION IS BE DELETED, A NUMBER OF OPERATIONS MAY HAVE TO BE ; PERFORMED TO EFFECT ALL NECESSARY CLEANUP, DEPENDING ON THE CURRENT ; STATE OF THE REGION AS DETERMINED BY THE BITS PS.OUT AND PS.CKP. NOTE ; THAT IF THE REGION IS OUT OF MEMORY, IT CANNOT BE IN THE PARTITION ; WAIT QUEUE, LOADER OR LOADER QUEUE. THIS IS DUE TO THE FACT THAT ; SINCE THE CURRENT TASK IS RUNNING, IT HAS EITHER NOT BEEN MAPPED (COM- ; MON CANNOT BE CONTENDING FOR MEMORY) OR MAPPED AND NOT BLOCKED (COMMON ; IS IN MEMORY). ON DELETION, IF THE REGION HAS A NAME IT IS REMOVED ; FROM THE COMMON BLOCK DIRECTORY. ADDITIONAL CLEANUP ACTIONS FOR THE ; FOUR POSSIBLE STATES OF THE REGION ARE: ; ; (PS.OUT=0,PS.CKP=0 => COMMON IS IN MEMORY) - RELEASE MEMORY ; DELETE REGION PCB AND ANY DISK PCB. ; ; (PS.OUT=0,PS.CKP=1 => COMMON IS IN PROCESS OF BEING CHECKPOINTED ; OUT) - RELEASE MEMORY AND COUNT ON THE LOADER TO DETECT ; THIS CONDITION AND RELEASE ANY CHECKPOINT SPACE AND ; DELETE REGION PCB AND DISK PCB. ; ; (PS.OUT=1,PS.CKP=0 => REGION NEVER LOADED) - DELETE REGION PCB ; AND ANY DISK PCB. ; ; (PS.OUT=1,PS.CKP=1 => REGION IS CHECKPOINTED OUT) - RELEASE ; CHECKPOINT SPACE AND DELETE REGION PCB AND DISK PCB. ; ; INPUTS: ; ; R0=REGION PCB ADDRESS. ; ; OUTPUTS: ; ; NONE. ;- $DELRG::BIT #PS.COM,P.STAT(R0) ;IS IT A NAMED COMMON? BEQ 40$ ;IF EQ NO TST P.NAM(R0) ;DOES THE REGION HAVE A NAME? BEQ 40$ ;IF EQ NO MOV #$CBDHD-P.CBDL,R1 ;POINT TO COMMON BLOCK DIRECTORY HEAD 30$: CMP P.CBDL(R1),R0 ;POINTING TO ONE TO DELETE? BEQ 35$ ;IF EQ YES MOV P.CBDL(R1),R1 ;POINT TO NEXT BR 30$ ; 35$: MOV P.CBDL(R0),P.CBDL(R1) ;UNLINK FROM COMMON BLK DIRECTORY 40$: BIS #PS.DEL,P.STAT(R0) ;MARK REGION FOR DELETE BIT #PS.OUT,P.STAT(R0) ;IS REGION IN MEMORY? BNE 50$ ;IF NE NO MOV R0,R1 ;COPY PCB ADDRESS TST P.DPCB(R0) ;DOES IT HAVE A DISK PCB? BEQ 45$ ;IF EQ NO CALLR $ICHKP ;INITIATE CHECKPOINT & LET LOADER FINISH 45$: MOV R0,-(SP) ;SAVE PCB ADDRESS CALL $RLPR1 ;FREE MEMORY MOV (SP)+,R0 ;RESTORE PCB ADDRESS 50$: CALLR $RLCPS ;RELEASE CHECKPOINT SPACE ;+ ; **-$DETRG-DETACH REGION BY ATTACHMENT DESCRIPTOR ADDRESS ; ; THIS ROUTINE DETACHES A TASK FROM A REGION AND DEALLOCATES THE ATTACHMENT ; DESCRIPTOR. ON THE LAST DETACH OF A REGION IT IS CHECKED FOR DELETION. ; WHEN APPRORIATE, $NXTSK IS CALLED. ; ; ; NOTE: THE DETACH REGION ROUTINE MAKES USE OF THE FOLLOWING RELATIONSHIPS ; IN THE DATA STRUCTURES AS SHOWN IN THE DIAGRAM BELOW: ; ; A.TCB IS AT OFFSET 4 FROM A.PCBL ; A.PCB IS AT OFFSET 4 FROM A.TCBL ; ; ; PCB ; +-------+ ; | | ; | | ; |-------| ADB ; | P.ATT |--| +---------------+ +---------------+ ; |-------| |--->| A.PCBL |------>| 0 |<------+ ; +----|-------| |---------------| |---------------| | ; | | | | A.IOC | A.PRI | | | | | ; | | | |---------------| |---------------| | ; | +-------+ | A.TCB | | | | ; | |---------------| |---------------| | ; | TCB |--->| A.TCBL |------>| 0 | | ; | +-------+ | |---------------| |-->|---------------| | ; | | | | |A.MPCT | A.STAT| | | | | | ; | | | | |---------------| | |---------------| | ; | |-------| | | A.PCB | | | | | ; | | T.ATT |--| +---------------+ | +---------------+ | ; | |-------| | | ; | |-------|---------------------------| | ; | | | | ; | | | | ; | +-------+ | ; | | ; +--------------------------------------------------------------------+ ; ; ; ; THE ROUTINE BELOW CLEARS THE KEY TO SEARCH ON, AND CLEARS OFFSET 4 FROM ; THE LINK WORD BEFORE CALLING $QRMVT. $QRMVT COMPARES OFFSET 4 IN EACH ; ELEMENT ON THE LIST WITH THE KEY. THE ZERO KEY WILL MATCH THE ATTACHMENT ; DESCRIPTOR WHICH HAS BEEN MARKED WITH A ZERO. ; ; INPUTS: ; ; R5=ADDRESS OF ATTACHMENT DESCRIPTOR ; ; OUTPUTS: ; ; R0,R1,R2,R3 ARE MODIFIED. ;- $DETRG::MOV A.PCB(R5),R0 ;POINT TO PCB OF REGION ADD #P.ATT,R0 ;POINT TO ATTACHMENT DESCR LISTHEAD CLR R1 ;CLEAR SEARCH KEY MOV A.TCB(R5),-(SP) ;SAVE TCB ADDRESS CLR A.TCB(R5) ;MARK ATTACHMENT DESCRIPTOR FOR REMOVAL CALL $QRMVT ;REMOVE DESCRIPTOR FROM PCB'S QUEUE TST (R0) ;IS ANYONE ELSE ATTACHED? (P.ATT) BNE 55$ ;IF NE YES SUB #P.ATT,R0 ;POINT TO START OF PCB BIT #PS.PER,P.STAT(R0) ;PARITY ERROR IN REGION? BEQ 22$ ;IF EQ NO MOV $FXRPT,R0 ;GET TCB ADDRESS OF RECOVERY TASK BEQ 55$ ;IF EQ IT IS NOT INSTALLED CMP R0,(SP) ;PARITY ERROR IN RECOVERY TASK? BEQ 55$ ;IF EQ YES CALL $EXRQN ;REQUEST THE RECOVERY TASK BR 55$ ;DO NOT DELETE REGION 22$: TST P.NAM(R0) ;IS THIS A NAMED REGION? BNE 25$ ;IF NE YES MOV (SP),R1 ;PICK UP TCB ADDRESS MOV T.PCBV(R1),R1 ;POINT TO PCB VECTOR BEQ 26$ ;IF EQ THERE IS NONE CMP R0,2(R1) ;READ ONLY REGION OF MU TASK? BNE 26$ ;IF NE NO, MUST DELETE BR 55$ ;ELSE DO NOT DELETE 25$: BIT #PS.DEL,P.STAT(R0) ;IS REGION MARKED FOR DELETE? BEQ 55$ ;IF EQ NO 26$: CALL $DELRG ;DELETE THE REGION 55$: MOV (SP)+,R0 ;RESTORE TCB ADDRESS ADD #T.ATT,R0 ;POINT TO ATTACHMENT DESCRIPTOR LISTHEAD CLR R1 ;CLEAR SEARCH KEY CLR A.PCB(R5) ;MARK ATTACHMENT DESCRIPTOR FOR REMOVAL CALL $QRMVT ;REMOVE DESCRIPTOR FROM TCB'S LIST MOV R5,R0 ;COPY DESCRIPTOR ADDRESS MOV #A.LGTH,R1 ;SET SIZE TO DEALLOCATE CALLR $DEACB ;DEALLOCATE ATTACHMENT DESCRIPTOR .END